#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <linux/io.h>

#include <asm/div64.h>

#include <asm/mach/map.h>
#include <mach/regs-lcd.h>
#include <mach/regs-gpio.h>
#include <mach/fb.h>
static struct fb_info *myfb_info;
static struct fb_ops myfb_ops = {
	.owner		= THIS_MODULE,
	.fb_fillrect	= cfb_fillrect,
	.fb_copyarea	= cfb_copyarea,
	.fb_imageblit	= cfb_imageblit,
};
/*1.入口函数*/
int __init lcd_drv_init(void)
{
    dma_addr_t dma_addr;
    /* 1.1 分配fb_info结构体*/
    // 第一个参数很有意思 是出来fb_info外在多分配一些区域存放我们想要的私有数据
    myfb_info = framebuffer_alloc(0,NULL);

    /* 1.2 设置 fb_info结构体*/
    /* a. var */
    myfb_info->var.xres = 1024;
    myfb_info->var.yres = 720;
    myfb_info->var.bits_per_pixel = 16;//每个像素用16位表示
    //RGB 565
    myfb_info->var.red.offset = 11;
    myfb_info->var.red.length = 5;
    myfb_info->var.green.offset = 5;
    myfb_info->var.green.length = 6;
    myfb_info->var.blue.offset = 0;
    myfb_info->var.blue.length = 5;
    /* b fix*/
    
    myfb_info->fix.smem_len = myfb_info->var.xres * myfb_info->var.yres * myfb_info->var.bits_per_pixel / 8;
    if(myfb_info->var.bits_per_pixel == 24) /*RGB88 分配了32个字节*/
        myfb_info->fix.smem_len = myfb_info->var.xres * myfb_info->var.yres * 4;
    myfb_info->screen_base = dma_alloc_wc(NULL, myfb_info->fix.smem_len, &dma_addr,
					 GFP_KERNEL);/*虚拟地址*/
    myfb_info->fix.smem_start = dma_addr; /*显存的物理地址*/
    myfb_info->fix.type = FB_TYPE_PACKED_PIXELS;
    myfb_info->fix.visual = FB_VISUAL_TRUECOLOR;
    /* c fbops*/
    /* 1.3 注册 fb_info结构体*/
    myfb_info->fbops = &myfb_ops;
    register_framebuffer(myfb_info);
    /* 1.4 硬件操作代码*/
    return 0;
}
/*2.出口函数*/
static void __exit lcd_drv_exit(void)
{
    /*2.1 反注册fb_info结构体*/
    unregister_framebuffer(myfb_info);
    /* 2.2 释放fb_info结构体*/
    framebuffer_release(myfb_info);
}

module_init(lcd_drv_init);
module_exit(lcd_drv_exit);

MODULE_AUTHOR("me");
MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>");
MODULE_DESCRIPTION("Framebuffer driver for the s3c2410");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:s3c2410-lcd");
MODULE_ALIAS("platform:s3c2412-lcd");